package main

import (
	"crypto/tls"
	"gintest/database"
	"gintest/routers"
	"log"
	"net/http"
	"time"
	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
	"gintest/core/config"
	"strings"
	"gintest/until"
	"gintest/core/consul"
	"gintest/core/rpc/rclient"
)

var (
	g errgroup.Group
)

func main() {
	//读取配置
	config.Sconfig = new(config.Config)
	config.Sconfig.InitConfig("./config.ini")

	//初始化数据库
	database.Init()
	if config.Sconfig.Read("db","open")=="true"{
		defer database.SqlDB.Close()
	}
	if config.Sconfig.Read("redis","open")=="true"{
		defer database.RedisDB.Close()
	}
	
	//开发模式
	if config.Sconfig.Read("default","mode")=="release"{
		gin.SetMode(gin.ReleaseMode)
	} else if config.Sconfig.Read("default","mode")=="debug"{
		gin.SetMode(gin.DebugMode)
	}
	//启动任务
	until.InitTask()
	
	//是否强制使用https
	var forceHandler http.Handler
	if config.Sconfig.Read("cert","force")=="true"{
		forceHandler=http.HandlerFunc(routers.Redirect)
	}else{
		forceHandler=http.HandlerFunc(routers.InitProxy)
	}
	//服务
	server01 := &http.Server{
		Addr:         ":80",
		Handler:      forceHandler, //http.HandlerFunc(routers.Redirect)
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	server02 := &http.Server{
		Addr:         ":443",
		Handler:      http.HandlerFunc(routers.InitProxy),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
		TLSConfig:    InitCert(),
	}
	server03 := &http.Server{
		Addr:         ":8082",
		Handler:      routers.InitRouter(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}
	g.Go(func() error {
		return server01.ListenAndServe()
	})

	g.Go(func() error {
		return server02.ListenAndServeTLS("", "")
	})

	g.Go(func() error {
		return server03.ListenAndServe()
	})
	//consul 使用RPC必须先初始化consul
	if config.Sconfig.Read("consul","open")=="true"{
		consul.Init()
	}
	//rpc client
	if config.Sconfig.Read("rclient","open")=="true" && config.Sconfig.Read("consul","open")=="true"{
		rclient.Init()
		defer rclient.Close()
	}

	println("成功")
	if err := g.Wait(); err != nil {
		log.Fatal(err)
	}
}

//加载证书列表
func InitCert() *tls.Config {
	crt:=strings.Split(config.Sconfig.Read("cert","crt"),",")
	key:=strings.Split(config.Sconfig.Read("cert","key"),",")

	cfg := &tls.Config{}
	for i:=0;i<len(crt);i++{
		cert,err:= tls.LoadX509KeyPair(crt[i], key[i])
		if err != nil {
			log.Fatal(err)
		}
		cfg.Certificates = append(cfg.Certificates, cert)
	}
	cfg.BuildNameToCertificate()
	return cfg
}
